﻿using System.Collections.Generic;
using Network;
using UnityEngine;
using GameProtocols;
using Framework;
using LitJson;
using Shipwar.SDK;
using System;
using System.Collections;

public class ProcGame : Proc
{

    public ProcGame()
        : base(ProcType.PROC_GAME)
    {
    }

    public override void process()
    {
        NetManager.Instance.Tick(Time.deltaTime);
        VisualEntityManager.Instance.DispatchMsg();
    }

    public override void onBegin(object[] param)
    {
        RegistUIEvent();
        RegistNetworkEvent();
        string host = (string)param[0]; ushort port = (ushort)param[1]; uint conv = (uint)param[2];
        SceneManager.Instance.BeginLoadScene(new List<string>() { "battle" , "S04"}, () =>
        {
            string prefabPath = string.Format("Prefab/roles/{0}_mx", 405000018);
            SimplePool.Preload(prefabPath, 2);
            SceneManager.Instance.EndLoadScene();
            IsInit = true;
            BeginGame(host, port, conv);
        });
    }

    void BeginGame(string host, ushort port, uint conv)
    {
        GameManager.Instance.Init(FightGame.Instance);
        PlayerManager.Instance.Reset();
        LockstepEngine.Instance.Reset();
        NetManager.Instance.UdpConnect(host, port, conv);
        PKG_SYN_STATE_REQ syncStateReq = new PKG_SYN_STATE_REQ();
        syncStateReq.frameNo = LockstepEngine.Instance.mNextFrameNo;
        NetManager.Instance.SendUdpMessage((ushort)ProtoId.MSG_SYN_STATE_REQ, syncStateReq);
    }

    public override void onEnd()
    {
        GameManager.Instance.Destroy();
        LockstepEngine.Instance.Destroy();
        NetManager.Instance.UdpClose();
        VisualEntityManager.Instance.Destroy();
        UnregistUIEvent();
        UnregistNetworkEvent();
    }

    void RegistUIEvent()
    {

    }

    void RegistNetworkEvent()
    {
        NetManager.Instance.tcpConc.connectionDelegate += onReconnectSuccess;
        //NetManager.Instance.RegistMsg((ushort)JsonMsgId.LeaveRoomResponse, onLeaveRoom);
        NetManager.Instance.RegistMsg((ushort)JsonMsgId.LogonResponse, onReLogin);
    }

    void UnregistUIEvent()
    {

    }

    void UnregistNetworkEvent()
    {
        NetManager.Instance.tcpConc.connectionDelegate -= onReconnectSuccess;
        //NetManager.Instance.UnregistMsg((ushort)JsonMsgId.LeaveRoomResponse, onLeaveRoom);
        NetManager.Instance.UnregistMsg((ushort)JsonMsgId.LogonResponse);
    }

    public static void requestLeaveRoom(Action onFinish)
    {
        CoroutineDecorator.Instance.New(DoRequestLeaveRoom(onFinish));
    }

    static IEnumerator DoRequestLeaveRoom(Action onFinish)
    {
        Spinning.Instance.SetActive(true);
        //yield return NetManager.Instance.sendKcpRequestMsg((ushort)JsonMsgId.LeaveRoomRequest, "", 5);
        Spinning.Instance.SetActive(false);

        JsonData json = (JsonData)CoroutineDecorator.Instance.returnValueRegister;
        if(json == null)
        {
            Mainloop.Instance.ShowNoNetworkTips();
            yield break;
        }

        onLeaveRoom(json);
        if (onFinish != null)
            onFinish();
    }

    static void onLeaveRoom(object msg)
    {
        JsonData json = (JsonData)msg;
        NetManager.Instance.UdpClose();
    }

    public override void onTcpDisconnected()
    {
        NetManager.Instance.Connect(Config.JavaServerIp, Config.JavaTcpPort);
    }

    void onReconnectSuccess()
    {
        JsonData loginData = new JsonData();
        loginData["guid"] = SDK.GetInstance().currentUser.AppUID;
        loginData["token"] = SDK.GetInstance().currentUser.APPToken;
        loginData["channel"] = "JJ";
        loginData["version"] = Mainloop.Instance.AppVersion;
        loginData["firstLogon"] = false;
        NetManager.Instance.sendTcpMsg((ushort)JsonMsgId.LogonRequest, loginData.ToJson());
    }

    void onReLogin(object msg)
    {
        JsonData json = (JsonData)msg;
        int code = (int)json["code"];
        if (code == 0)
        {
            JsonData kcpState = json["kcpState"];
            if (kcpState == null)//战斗结束
            {
                Mainloop.Instance.ctrl.changeProc(ProcType.PROC_LOBBY);
            }
        }
        else
        {
            Mainloop.Instance.ctrl.changeProc(ProcType.PROC_LOGIN);
        }
    }
}
